package com.common.base.security;

import android.text.TextUtils;
import android.util.Log;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 安全工具
 * 封装了加解密及签名等算法
 * Created by sosou on 2017/12/19.
 */

public class SecurityUtils
{
    /**
     * SHA签名算法
     * SHA-256
     */
    public static final String SIGN_SHA256 = "OvSa1rXAPH7zIGMBc16fkw==";

    /**
     * 编码格式
     */
    public static final String UTF_8 = "UTF-8";

    /**
     * RSA加密算法
     * @param content 明文
     * @param publicKey 公钥
     * @return 密文
     */
    public static String encryptRSAWPublicKey(String content, String publicKey)
    {
        byte[] byteContent = (byte[]) null;
        byte[] target = (byte[]) null;
        try
        {
            byteContent = content.getBytes(UTF_8);
            target = RSAUtils.encryptByPublicKey(byteContent, publicKey);

            Base64Utils Base64 = new Base64Utils();
            
            return Base64.encode(target);
        }
        catch (UnsupportedEncodingException e1)
        {
            Log.e("SecurityUtils",e1.getMessage());
        }
        catch (Exception e)
        {
            Log.e("SecurityUtils",e.getMessage());
        }
        return null;
    }

    /**
     * RSA解密算法
     * @param content 密文
     * @param privateKey 私钥
     * @return 明文
     */
    public static String decryptRSAWPrivateKey(String content, String privateKey)
    {
        byte[] byteContent = (byte[]) null;
        byte[] target = (byte[]) null;
        try
        {
            Base64Utils SBase64 = new Base64Utils();
            byteContent = SBase64.decode(content);

            target = RSAUtils.decryptByPrivateKey(byteContent, privateKey);
            return new String(target, UTF_8);
        }
        catch (UnsupportedEncodingException e1)
        {
            Log.e("SecurityUtils",e1.getMessage());
        }
        catch (Exception e)
        {
            Log.e("SecurityUtils",e.getMessage());
        }
        return null;
    }

    /**
     * 签名算法
     * @param src 源字符串
     * @param algorithm 签名算法
     * @return 签名字符串
     */
    public static String sign(String src, String algorithm)
    {
        MessageDigest md = null;
        String target = null;
        try
        {
            byte[] bt = src.getBytes(UTF_8);
            md = MessageDigest.getInstance(algorithm);
            md.update(bt);

            target = parseByte2HexStr(md.digest());
        }
        catch (Exception e)
        {
            Log.e("SecurityUtils",e.getMessage());
        }

        return target;
    }

    /**
     * 哈希算法
     * @param buf 源字节数组
     * @return 哈希字符串
     */
    public static String parseByte2HexStr(byte[] buf)
    {
        StringBuilder sb = new StringBuilder();

        String hex = null;

        for (int i = 0; i < buf.length; i++)
        {
            hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1)
            {
                hex = '0' + hex;
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    public static String getFileSignature(File file, STypeEnum typeEnum) {
        MessageDigest digest;
        String type = "";
        switch (typeEnum) {
            case MD5:
                type = "MD5";
                break;
            case SHA1:
                type = "SHA-1";
                break;
            case SHA256:
                type = "SHA-256";
                break;
        }
        if (TextUtils.isEmpty(type)) {
//            LogUtil.e(Constants.LOG_TAG, "type undefined");
            return null;
        }
        try {
            digest = MessageDigest.getInstance(type);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }

        InputStream is;
        try {
            is = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
//            LogUtil.e(TAG, "Exception while getting FileInputStream");
            return null;
        }

        byte[] buffer = new byte[8192];
        int read;
        try {
            while ((read = is.read(buffer)) > 0) {
                digest.update(buffer, 0, read);
            }
            byte[] md5sum = digest.digest();
            BigInteger bigInt = new BigInteger(1, md5sum);
            String output = bigInt.toString(16);
            output = String.format("%32s", output).replace(' ', '0');
            return output;
        } catch (IOException e) {
            e.printStackTrace();
//            LogUtil.e(TAG,"Unable to process file for ");
            return null;
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
//                LogUtil.e(TAG, "Exception on closing inputstream:" );
            }
        }
    }
}
